import uuid
import datetime
import json
import os
import xlrd
import xlwt
import logging
from itertools import product
from utils.export_excel import ExportExcel
from django.conf import settings
from django.db.models import Count, Q
from django.http import JsonResponse, FileResponse
from django.shortcuts import render
from assets.models import *
from projs.models import ProjectProduct
from fort.models import *
from users.models import UserProfile
from utils.crypt_pwd import CryptPwd
from task.utils.ansible_api_v2 import ANSRunner
from django.contrib.auth.decorators import permission_required
from utils.sftp import SFTP
from utils.decorators import admin_auth
from django.urls import Resolver404
from django.core.paginator import Paginator
import re
import xlsxwriter
from projs.views import download_response
import importlib


@permission_required('assets.view_assets', raise_exception=True)
def get_assets_charts(request):
    assets_count = Assets.objects.all().count()
    online_assets_count = Assets.objects.filter(asset_status=0).count()
    break_assets_count = Assets.objects.filter(asset_status=2).count()
    unused_assets_count = Assets.objects.filter(asset_status=3).count()

    asset_data = []
    data_detail = []
    asset_types_count = Assets.objects.values('asset_type').annotate(dcount=Count('asset_type'))
    for m, n in product(asset_types_count, Assets.asset_types):
        if m.get('asset_type') == n[0]:
            asset_data.append({'asset_type': n[1], 'dcount': m.get('dcount')})

    server_types_count = ServerAssets.objects.values('server_type').annotate(dcount=Count('server_type'))
    for m, n in product(server_types_count, ServerAssets.server_types):
        if m.get('server_type') == n[0]:
            data_detail.append({'asset_type': n[1], 'dcount': m.get('dcount')})

    network_types_count = NetworkAssets.objects.values('network_type').annotate(dcount=Count('network_type'))
    for m, n in product(network_types_count, NetworkAssets.network_types):
        if m.get('network_type') == n[0]:
            data_detail.append({'asset_type': n[1], 'dcount': m.get('dcount')})

    office_types_count = OfficeAssets.objects.values('office_type').annotate(dcount=Count('office_type'))
    for m, n in product(office_types_count, OfficeAssets.office_types):
        if m.get('office_type') == n[0]:
            data_detail.append({'asset_type': n[1], 'dcount': m.get('dcount')})

    security_types_count = SecurityAssets.objects.values('security_type').annotate(dcount=Count('security_type'))
    for m, n in product(security_types_count, SecurityAssets.security_types):
        if m.get('security_type') == n[0]:
            data_detail.append({'asset_type': n[1], 'dcount': m.get('dcount')})

    storage_types_count = StorageAssets.objects.values('storage_type').annotate(dcount=Count('storage_type'))
    for m, n in product(storage_types_count, StorageAssets.storage_types):
        if m.get('storage_type') == n[0]:
            data_detail.append({'asset_type': n[1], 'dcount': m.get('dcount')})

    software_types_count = SoftwareAssets.objects.values('software_type').annotate(dcount=Count('software_type'))
    for m, n in product(software_types_count, SoftwareAssets.software_types):
        if m.get('software_type') == n[0]:
            data_detail.append({'asset_type': n[1], 'dcount': m.get('dcount')})

    admin_records = AdminRecord.objects.select_related('admin_login_user').all().order_by('-admin_start_time')[:5]

    return render(request, 'assets/assets_charts.html', locals())


@permission_required('assets.view_assets', raise_exception=True)
def get_assets_list(request):
    from api.filter import is_expired_types
    is_expired_ = is_expired_types
    asset_types = Assets.asset_types
    asset_status_ = Assets.asset_status_
    asset_status = request.GET.get('asset_status')
    environment_choice_ = environment_choice
    assets = None
    if asset_status:
        db_status = tuple(filter(lambda x: x[1] == asset_status, Assets.asset_status_))[0][0]
        assets = Assets.objects.filter(asset_status=db_status)
    else:
        assets = Assets.objects.all()
    return render(request, 'assets/assets_list.html', locals())


@permission_required('assets.view_ipsegment', raise_exception=True)
def get_ipgroup_list(request):
    results = IPSegment.objects.annotate(valid_IP_segment_count = Count('IP_segment', filter=Q(IP_segment__IP_status=1)))
    IP_environment_ = IPSegment.IP_environment_
    return render(request, 'assets/ipgroup_list.html', locals())


@permission_required('assets.add_assets', raise_exception=True)
def add_asset(request):
    asset_types = Assets.asset_types
    server_types = ServerAssets.server_types
    network_types = NetworkAssets.network_types
    office_types = OfficeAssets.office_types
    security_types = SecurityAssets.security_types
    storage_types = StorageAssets.storage_types
    software_types = SoftwareAssets.software_types
    asset_status_ = Assets.asset_status_
    asset_environment_ = Assets.asset_environment_
    asset_providers = AssetProvider.objects.all()
    asset_admin = request.user
    asset_idcs = IDC.objects.all()
    asset_cabinets = Cabinet.objects.select_related('idc')
    return render(request, 'assets/add_asset.html', locals())


@permission_required('assets.add_assets', raise_exception=True)
def add_server_asset(request):
    asset_types = Assets.asset_types
    server_types = ServerAssets.server_types
    asset_status_ = Assets.asset_status_
    asset_environment_ = Assets.asset_environment_
    asset_admin = request.user
    return render(request, 'assets/add_server_asset.html', locals())


@permission_required('assets.add_assets', raise_exception=True)
def add_base_asset(request):
    asset_idcs = IDC.objects.all()
    asset_cabinets = Cabinet.objects.select_related('idc')
    asset_providers = AssetProvider.objects.all()
    return render(request, 'assets/add_base_asset.html', locals())


def find_ip_segment(request):
    if request.method == 'POST':
        ip_segment = IPSegment.objects.all()
        results = [{'id': i.id, 'text': i.segment} for i in ip_segment]
        return JsonResponse({'code': 200, 'results': results})


def find_ip(request):
    if request.method == 'POST':
        ip_state = request.POST.get('IP_state')
        ip_segment = request.POST.get('IP_segment')
        valid_groups = Assets.objects.select_related('asset_management_ip').filter(asset_management_ip__IP_segment=ip_segment, asset_management_ip__IP_status=1).values('asset_management_ip__id','asset_management_ip__IP').distinct()
        # IP_state 0表示空闲，1表示占用，2表示全部
        if ip_state=='1':
            return JsonResponse({'code': 200, 'results': [{'id': i['asset_management_ip__id'], 'text': i['asset_management_ip__IP']} for i in valid_groups]})
        else:
            all_groups = IPGroup.objects.filter(IP_segment=ip_segment, IP_status=1).values('id', 'IP')
            if ip_state=='0':
                valid_groups_list = list(map(lambda x: x['asset_management_ip__id'], valid_groups))
                invalid_groups = [{'id': i['id'], 'text': i['IP']} for i in all_groups if i['id'] not in valid_groups_list]
                return JsonResponse({'code': 200, 'results': invalid_groups})
            else:
                return JsonResponse({'code': 200, 'results': [{'id': i['id'], 'text': i['IP']} for i in all_groups]})


def find_idle_ip(request):
    if request.method == 'POST':
        ip_segment = request.POST.get('IP_segment')
        valid_groups = Assets.objects.select_related('asset_management_ip').filter(asset_management_ip__IP_segment=ip_segment).values('asset_management_ip__id','asset_management_ip__IP').distinct()
        all_groups = IPGroup.objects.filter(IP_segment=ip_segment).values('id', 'IP')
        valid_groups_list = list(map(lambda x: x['asset_management_ip__id'], valid_groups))
        invalid_groups = [{'id': i['id'], 'text': i['IP']} for i in all_groups if i['id'] not in valid_groups_list]
        return JsonResponse({'code': 200, 'results': invalid_groups})


def find_hosted_on(request):
    if request.method == 'GET':
        search = request.GET.get('search')
        page = request.GET.get('page')
        offset = request.GET.get('offset')
        assets = Assets.objects.filter(Q(asset_management_ip__IP__contains=search)|Q(asset_nu__icontains=search)).values_list('id','asset_nu','asset_management_ip__IP')
        group = Paginator(assets, offset).page(page)
        results = [{'id': i[0], 'text': i[1]+'-'+i[2]} for i in group.object_list]
        return JsonResponse({'code': 200, 'results': results, 'page' :group.paginator.num_pages, 'total_count': group.paginator.count})

@permission_required('assets.change_assets', raise_exception=True)
def update_asset(request, asset_type, pk):
    if request.method == 'GET':
        asset = Assets.objects.get(id=pk)
        asset_types = Assets.asset_types
        asset_status_ = Assets.asset_status_
        asset_admins = UserProfile.objects.all()
        asset_environment_ = Assets.asset_environment_
        asset_providers = AssetProvider.objects.all()
        asset_idcs = IDC.objects.all()
        return render(request, 'assets/update_asset.html', locals())


@permission_required('assets.add_assets', raise_exception=True)
def server_facts(request):
    if request.method == 'POST':
        pk = request.POST.get('pk')
        module = request.POST.get('module')
        username = request.POST.get('username')
        try:
            server_obj = FortServerUser.objects.get(id=pk)
            password = server_obj.fort_password
            server = server_obj.fort_server.server
            server_ip = server.IP
            server_id = server.id
            port = server_obj.fort_server.port
        except:
            raise Resolver404

        resource = [{"ip": server_ip, "port": int(port),
                     "username": username,
                     "password": CryptPwd().decrypt_pwd(password)}]

        try:
            ans = ANSRunner(resource, become='yes', become_method='sudo', become_user='root')
            ans.run_module(host_list=[server_ip], module_name=module, module_args="")

            for data in ans.get_module_results:
                if module == 'setup':
                    if 'success' in data:
                        server_info, server_model, nks = ans.handle_setup_data(data)
                        Assets.objects.filter(asset_management_ip=server_id).update(
                            asset_model=server_model
                        )
                        ServerAssets.objects.select_related('assets').filter(assets__asset_management_ip=server_id).update(**server_info)

                        assets = Assets.objects.filter(asset_management_ip=server_id)
                        for asset in assets:
                            for nk in nks:
                                mac = nk.get('network_card_mac')
                                NetworkCardAssets.objects.select_related('asset').update_or_create(defaults=nk, asset=asset,
                                                                                                   network_card_mac=mac)
                        return JsonResponse({'code': 200, 'msg': '收集完成！'})
                    else:
                        return JsonResponse({'code': 500, 'msg': '收集失败！{}'.format(data[data.index('>>') + 1:])})
                elif module == 'get_mem':
                    if 'success' in data:
                        mem_infos = ans.handle_mem_data(data)

                        assets = Assets.objects.filter(asset_management_ip=server_id)
                        for asset in assets:
                            for mem_info in mem_infos:
                                ram_slot = mem_info.get('ram_slot')
                                RamAssets.objects.select_related('asset').update_or_create(defaults=mem_info, asset=asset,
                                                                                           ram_slot=ram_slot)
                        return JsonResponse({'code': 200, 'msg': '收集完成！'})
                    else:
                        return JsonResponse({'code': 500, 'msg': '收集失败！{}'.format(data[data.index('>>') + 1:])})
        except Exception as e:
            return JsonResponse({'code': 500, 'msg': str(e)})


@permission_required('assets.view_assets', raise_exception=True)
def get_asset_info(request, pk):
    asset = Assets.objects.get(id=pk)
    return render(request, 'assets/asset_info.html', locals())

@permission_required(['assets.change_assets','assets.change_serverassets'], raise_exception=True)
def edit_asset_info(request, pk):
    asset = Assets.objects.get(id=pk)
    return render(request, 'assets/edit_asset_info.html', locals())

@permission_required('assets.add_assets', raise_exception=True)
def import_assets(request):
    if request.method == 'POST':
        file = request.FILES.get('file')
        filename = os.path.join(settings.BASE_DIR, 'upload', file.name)
        if not os.path.exists(os.path.dirname(filename)):
            os.makedirs(os.path.dirname(filename))
        with open(filename, 'wb') as f:
            for chunk in file.chunks():
                f.write(chunk)

        try:
            # 只支持倒入IP为空或者IP不被占用的服务器资产
            xl_file = xlrd.open_workbook(filename)
            sheet_names = xl_file.sheet_names()
            data_list = []
            sheet_obj = xl_file.sheet_by_name(sheet_names[0])
            for i in range(1, sheet_obj.nrows):
                data_list.append(sheet_obj.row_values(i))
            suc = 0
            i = 1
            for data in data_list:
                if not data[0]:
                    return JsonResponse({'code': 500, 'msg': '第%d行第1列的服务器类型不能为空！' % (i+1)}, status=500)
                if data[0] and data[0] not in dict(ServerAssets.server_types).values():
                    return JsonResponse({'code': 500, 'msg': '第%d行第1列的服务器类型无效！' % (i+1)}, status=500)
                if not data[1]:
                    return JsonResponse({'code': 500, 'msg': '第%d行第2列的资产编号/资产名称不能为空！' % (i+1)}, status=500)
                if data[2] and ProjectProduct.objects.filter(product_name=data[2]).count() == 0:
                    return JsonResponse({'code': 500, 'msg': '第%d行第3列的对应产品不存在！'%(i+1)}, status=500)
                if not data[5]:
                    return JsonResponse({'code': 500, 'msg': '第%d行第6列的设备环境不能为空！' % (i+1)}, status=500)
                if data[5] and data[5] not in dict(Assets.asset_environment_).values():
                    return JsonResponse({'code': 500, 'msg': '第%d行第6列的设备环境无效！' % (i+1)}, status=500)
                if not data[6]:
                    return JsonResponse({'code': 500, 'msg': '第%d行第7列的申请/购买日期不能为空！' % (i+1)}, status=500)
                if data[6] and not isinstance(data[6], float) and not (re.compile('^[1-9]\d{3}-([1-9]|0[1-9]|1[0-2])-([1-9]|0[1-9]|[1-2][0-9]|3[0-1])$').match(data[6]) or re.compile('^[1-9]\d{3}/([1-9]|0[1-9]|1[0-2])/([1-9]|0[1-9]|[1-2][0-9]|3[0-1])$').match(data[6])):
                    return JsonResponse({'code': 500, 'msg': '第%d行第7列的日期格式不正确，只支持yyyy-mm-dd或者yyyy/mm/dd的格式！' % (i+1)}, status=500)
                if not data[7]:
                    return JsonResponse({'code': 500, 'msg': '第%d行第8列的到期/过保日期不能为空！' % (i+1)})
                if data[7] and not isinstance(data[7], float) and not (re.compile('^[1-9]\d{3}-([1-9]|0[1-9]|1[0-2])-([1-9]|0[1-9]|[1-2][0-9]|3[0-1])$').match(data[7]) or re.compile('^[1-9]\d{3}/([1-9]|0[1-9]|1[0-2])/([1-9]|0[1-9]|[1-2][0-9]|3[0-1])$').match(data[7])):
                    return JsonResponse({'code': 500, 'msg': '第%d行第8列的日期格式不正确，只支持yyyy-mm-dd或者yyyy/mm/dd的格式！' % (i+1)}, status=500)
                if not data[10]:
                    return JsonResponse({'code': 500, 'msg': '第%d行第11列的状态不能为空！' % (i+1)}, status=500)
                if data[10] and data[10] not in dict(Assets.asset_status_).values():
                    return JsonResponse({'code': 500, 'msg': '第%d行第11列的状态无效！' % (i+1)}, status=500)
                i += 1
            for data in data_list:
                try:
                    if data[4] and IPGroup.objects.filter(IP=data[4], IP_status=1).count() == 0:
                        continue
                    assets = {
                        'asset_type': 'server',
                        'asset_nu': data[1],
                        'asset_product': ProjectProduct.objects.get(product_name=data[2]) if data[2] else None,
                        'asset_environment': [v[0] for v in Assets.asset_environment_ if v[1]==data[5]][0] if data[5] else 0,
                        'asset_status': [v[0] for v in Assets.asset_status_ if v[1] == data[10]][0] if data[10] else 0,
                        'asset_management_ip': IPGroup.objects.get(IP=data[4], IP_status=1) if data[4] else None,
                        'asset_admin': UserProfile.objects.get(username=request.user),
                        'asset_applicant': data[8] if data[8] else '',
                        'asset_runner': data[9] if data[9] else '',
                        'asset_purchase_day':convert_date_excel_input(data[6]),
                        'asset_expire_day': convert_date_excel_input(data[7]),
                        'asset_memo': data[11],
                    }
                    # if data[0] == 'server':
                    asset_obj = Assets.objects.create(**assets)
                    server_asset = {
                        'server_type': [v[0] for v in ServerAssets.server_types if v[1]==data[0]][0] if data[0] else 1,
                        'hosted_on': ServerAssets.objects.select_related('assets').get(id=int(data[3])) if data[3] and int(data[0])!=0 else None,
                    }
                    ServerAssets.objects.update_or_create(assets=asset_obj, defaults=server_asset)
                    # elif data[0] == 'network':
                    #     NetworkAssets.objects.update_or_create(assets=asset_obj, network_type=int(data[13]))
                    # elif data[0] == 'office':
                    #     OfficeAssets.objects.update_or_create(assets=asset_obj, office_type=int(data[13]))
                    # elif data[0] == 'security':
                    #     SecurityAssets.objects.update_or_create(assets=asset_obj, security_type=int(data[13]))
                    # elif data[0] == 'storage':
                    #     StorageAssets.objects.update_or_create(assets=asset_obj, storage_type=int(data[13]))
                    # elif data[0] == 'software':
                    #     SoftwareAssets.objects.update_or_create(assets=asset_obj, software_type=int(data[13]))
                    suc += 1
                except:
                    pass
            return JsonResponse({'code': 200, 'msg': '成功导入'+str(suc)+'条记录！'})
        except Exception as e:
            return JsonResponse({'code': 500, 'msg': '导入失败！，{}'.format(e)}, status=500)

@permission_required('assets.add_assets', raise_exception=True)
def download_assets_template(request):
    if request.method == 'GET':
        tmp_dir = os.path.join(os.path.join(settings.BASE_DIR, 'media'), 'tmp')
        if not os.path.exists(tmp_dir):
            os.mkdir(tmp_dir)
        filename = os.path.join(tmp_dir, str(uuid.uuid1()).replace('-', '') + '.xlsx')
        workbook = xlsxwriter.Workbook(filename)
        worksheet = workbook.add_worksheet(u'服务器信息导入模板')
        title = workbook.add_format(
            {'bold': True, 'align': 'center', 'valign': 'vcenter', 'bg_color': '#007ee5', 'border': 1, })
        worksheet.set_column(0, 0, 10)
        worksheet.set_column(1, 1, 15)
        worksheet.set_column(2, 2, 15)
        worksheet.set_column(3, 3, 15)
        worksheet.set_column(4, 4, 15)
        worksheet.set_column(5, 5, 10)
        worksheet.set_column(6, 6, 15, workbook.add_format({'text_wrap': True, 'align': 'center', 'valign': 'vcenter', 'num_format': 'yyyy-mm-dd'}))
        worksheet.set_column(7, 7, 15, workbook.add_format({'text_wrap': True, 'align': 'center', 'valign': 'vcenter', 'num_format': 'yyyy-mm-dd'}))
        worksheet.set_column(8, 8, 15)
        worksheet.set_column(9, 9, 15)
        worksheet.set_column(10, 10, 15)
        worksheet.set_column(11, 11, 15)
        row = [u'服务器类型', u'资产编号/资产名称', u'对应产品', u'宿主机编号', u'管理IP', u'设备环境', u'申请/购买日期', u'到期/过保日期', u'申请人', u'负责人', u'状态', u'备注']
        for r in range(len(row)):
            worksheet.write(0, r, row[r], title)
        worksheet.freeze_panes(1, 0)
        worksheet.autofilter('A1:L1')
        worksheet.data_validation(1, 0, 10000, 0, {'validate': 'list', 'source': list(dict(ServerAssets.server_types).values())})
        worksheet.data_validation(1, 5, 10000, 5,
                                  {'validate': 'list', 'source': list(dict(Assets.asset_environment_).values())})
        worksheet.data_validation(1, 10, 10000, 10,
                                  {'validate': 'list', 'source': list(dict(Assets.asset_status_).values())})
        workbook.close()
        response = download_response(filename)
        return response

def convert_date_excel_input(d):
    if isinstance(d, float):
        return xlrd.xldate_as_datetime(d, 0)
    elif re.compile('^[1-9]\d{3}-([1-9]|0[1-9]|1[0-2])-([1-9]|0[1-9]|[1-2][0-9]|3[0-1])$').match(d):
        return datetime.datetime.strptime(d, '%Y-%m-%d')
    elif re.compile('^[1-9]\d{3}/([1-9]|0[1-9]|1[0-2])/([1-9]|0[1-9]|[1-2][0-9]|3[0-1])$').match(d):
        return datetime.datetime.strptime(d, '%Y/%m/%d')
    else:
        ''

@permission_required('assets.view_assets', raise_exception=True)
def export_assets(request):
    if request.method == 'POST':
        pks = request.POST.get('pks')
        server_row = network_row = office_row = security_row = storage_row = software_row = 1
        excel = None
        filename = '资产列表.xlsx'
        try:
            file = xlwt.Workbook(encoding='utf-8', style_compression=0)

            # 生成sheet
            server_sheet = file.add_sheet('server', cell_overwrite_ok=True)
            network_sheet = file.add_sheet('network', cell_overwrite_ok=True)
            office_sheet = file.add_sheet('office', cell_overwrite_ok=True)
            security_sheet = file.add_sheet('security', cell_overwrite_ok=True)
            storage_sheet = file.add_sheet('storage', cell_overwrite_ok=True)
            software_sheet = file.add_sheet('software', cell_overwrite_ok=True)

            # 导出数据
            for pk in json.loads(pks):
                asset = Assets.objects.get(id=int(pk))

                if asset.asset_type == 'server':
                    excel = ExportExcel(filename, excel_obj=file, asset_obj=asset, sheet_name=server_sheet)
                    excel.gen_body(server_row)
                    server_row = server_row + 1
                elif asset.asset_type == 'network':
                    excel = ExportExcel(filename, excel_obj=file, asset_obj=asset, sheet_name=network_sheet)
                    excel.gen_body(network_row)
                    network_row = network_row + 1
                elif asset.asset_type == 'office':
                    excel = ExportExcel(filename, excel_obj=file, asset_obj=asset, sheet_name=office_sheet)
                    excel.gen_body(office_row)
                    office_row = office_row + 1
                elif asset.asset_type == 'security':
                    excel = ExportExcel(filename, excel_obj=file, asset_obj=asset, sheet_name=security_sheet)
                    excel.gen_body(security_row)
                    security_row = security_row + 1
                elif asset.asset_type == 'storage':
                    excel = ExportExcel(filename, excel_obj=file, asset_obj=asset, sheet_name=storage_sheet)
                    excel.gen_body(storage_row)
                    storage_row = storage_row + 1
                elif asset.asset_type == 'software':
                    excel = ExportExcel(filename, excel_obj=file, asset_obj=asset, sheet_name=software_sheet)
                    excel.gen_body(software_row)
                    software_row = software_row + 1
                excel.gen_headers()
            excel.save_excel()
            response = FileResponse(excel.download_excel())
            response['Content-Type'] = 'application/octet-stream'
            response['charset'] = 'utf-8'
            response['Content-Disposition'] = 'attachment;filename="{filename}"'.format(filename=filename)
            return response
        except Exception as e:
            logging.getLogger().error('导出失败！{}'.format(e))


@admin_auth
def ssh_terminal(request, pk):
    try:
        server_obj = FortServerUser.objects.get(id=pk)
        download_file = request.GET.get('download_file')
        username = server_obj.fort_username
        password = server_obj.fort_password
        ssh_server_ip = server_obj.fort_server.server.IP
        port = server_obj.fort_server.port
    except:
        raise Resolver404
    if request.method == 'GET':
        if download_file:
            download_file_path = os.path.join(settings.MEDIA_ROOT, 'admin_files', request.user.username, 'download',
                                              ssh_server_ip)
            sftp = SFTP(ssh_server_ip, port, username,
                        CryptPwd().decrypt_pwd(password))
            response = sftp.download_file(download_file, download_file_path)
            return response
        else:
            remote_ip = request.META.get('REMOTE_ADDR')
            return render(request, 'assets/ssh_terminal.html', locals())
    elif request.method == 'POST':
        try:
            upload_file = request.FILES.get('upload_file')
            upload_file_path = os.path.join(settings.MEDIA_ROOT, 'fort_files', request.user.username, 'upload',
                                            ssh_server_ip)
            sftp = SFTP(ssh_server_ip, port, username,
                        CryptPwd().decrypt_pwd(password))
            sftp.upload_file(upload_file, upload_file_path)
            return JsonResponse({'code': 200, 'msg': '上传成功！文件默认放在{}用户家目录下'.format(server_obj.fort_username)})
        except Exception as e:
            return JsonResponse({'code': 500, 'msg': '上传失败！{}'.format(e)})


@admin_auth
def guacamole_terminal(request, pk):
    group_name = str(uuid.uuid4())
    server_obj = FortServerUser.objects.get(id=pk)
    guacamole_server_ip = server_obj.fort_server.server.IP
    remote_ip = request.META.get('REMOTE_ADDR')
    return render(request, 'assets/admin_guacamole.html', locals())


@admin_auth
def login_record(request):
    if request.method == 'GET':
        results = AdminRecord.objects.select_related('admin_login_user').all()
        linux_protocols = ['ssh', 'telnet']
        return render(request, 'assets/login_admin_record.html', locals())
    elif request.method == 'POST':
        start_time = request.POST.get('startTime')
        end_time = request.POST.get('endTime')
        new_end_time = datetime.datetime.strptime(end_time, '%Y-%m-%d') + datetime.timedelta(1)
        end_time = new_end_time.strftime('%Y-%m-%d')
        try:
            records = []
            search_records = AdminRecord.objects.select_related('admin_login_user').filter(
                admin_start_time__gt=start_time,
                admin_start_time__lt=end_time)
            for search_record in search_records:
                record = {
                    'id': search_record.id,
                    'admin_login_user': search_record.admin_login_user.username,
                    'admin_server': search_record.admin_server,
                    'admin_remote_ip': search_record.admin_remote_ip,
                    'admin_start_time': search_record.admin_start_time,
                    'admin_login_status_time': search_record.admin_login_status_time,
                    'admin_record_mode': search_record.get_admin_record_mode_display(),
                    'admin_record_cmds': search_record.admin_record_cmds
                }
                records.append(record)
            return JsonResponse({'code': 200, 'records': records})
        except Exception as e:
            return JsonResponse({'code': 500, 'error': '查询失败：{}'.format(e)})


@admin_auth
def admin_play(request, pk):
    record = AdminRecord.objects.select_related('admin_login_user').get(id=pk)
    if record.admin_record_mode in ['ssh', 'telnet']:
        return render(request, 'assets/ssh_play.html', locals())
    else:
        return render(request, 'assets/guacamole_play.html', locals())


@admin_auth
def telnet_terminal(request, pk):
    try:
        server_obj = FortServerUser.objects.get(id=pk)
        download_file = request.GET.get('download_file')
        username = server_obj.fort_username
        password = server_obj.fort_password
        telnet_server_ip = server_obj.fort_server.server.IP
        port = server_obj.fort_server.port
    except:
        raise Resolver404
    if request.method == 'GET':
        if download_file:
            download_file_path = os.path.join(settings.MEDIA_ROOT, 'admin_files', request.user.username, 'download',
                                              telnet_server_ip)
            sftp = SFTP(telnet_server_ip, port, username,
                        CryptPwd().decrypt_pwd(password))
            response = sftp.download_file(download_file, download_file_path)
            return response
        else:
            remote_ip = request.META.get('REMOTE_ADDR')
            if settings.GUACD_TELNET_PROTOCOL and importlib.util.find_spec('guacamole'):
                group_name = str(uuid.uuid4())
                fort_user_id = pk
                return render(request, 'fort/telnet_guacamole.html', locals())
            return render(request, 'assets/telnet_terminal.html', locals())
    elif request.method == 'POST':
        try:
            upload_file = request.FILES.get('upload_file')
            upload_file_path = os.path.join(settings.MEDIA_ROOT, 'fort_files', request.user.username, 'upload',
                                            telnet_server_ip)
            sftp = SFTP(telnet_server_ip, port, username,
                        CryptPwd().decrypt_pwd(password))
            sftp.upload_file(upload_file, upload_file_path)
            return JsonResponse({'code': 200, 'msg': '上传成功！文件默认放在{}用户家目录下'.format(server_obj.fort_username)})
        except Exception as e:
            return JsonResponse({'code': 500, 'msg': '上传失败！{}'.format(e)})
